<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      /*
      闭包：
        1. 概念:
          通过 Chrome 开发者工具调试查看，闭包一个 closure 对象，存在内部函数中，内部包含引用的外部函数局部变量
        
        2. 产生闭包的条件：
          - 函数嵌套
          - 内部函数引用外部函数的局部变量
          - 调用外部函数

        3. 优点/作用
          - 延长局部变量的生命周期
          - 让函数外部操作函数内部的数据

        4. 缺点
          - 可能会导致内存泄漏
          - 解决方案：及时释放，将内部函数的引用指向null，内部函数没有引用就会成为垃圾对象，就会被垃圾回收机制回收释放，闭包也随之释放  

        5. 生命周期
          - 产生：当内部函数定义执行完时
          - 死亡：当内部函数成为垃圾对象时

        6. 应用
          - React 高阶组件（HOC）-> 复用代码的方式
          - Vue2响应式原理 -> dep对象就是以闭包形式存在get/set方法
            将来读取属性触发get，内部会通过dep.depend方法建立响应式联系
            将来更新属性触发set，内部会通过dep.notify方法触发响应式更新
   */
      // var b = 2;
      // function fn1(a) {
      //   debugger;
      //   function fn2() {
      //     console.log(a, b);
      //   }
      //   console.log(fn2);
      // }
      // fn1(1);

      // 延长局部变量的生命周期
      // function fn1(a) {
      //   function fn2() {
      //     console.log(a);
      //     return a;
      //   }
      //   return fn2;
      // }
      // const fn2 = fn1(1);

      function fn1(a) {
        debugger;
        const fn2 = () => {
          console.log(a);
        };
        return fn2;
      }
      const fn2 = fn1(1);
    </script>
  </body>
</html>
